/***************************************************************************************************
  Copyright(C)   2011-2013
  All rights reserved.
  File Name: serialctl.h

  Description: 串口管理模块

        主要有与lcd屏通信串口，与环境亮度检测设备的通信串口，主备２台SLCD之间的通信串口

        主备SLCD之间的区别是：主设备与环境亮度检测设备有通信，副设备只能从主设备获取亮度
                            副设备的时间必须与主设备的一致


                                SLCD串口对应表

功能		串口号		串口类型         串口设备名        波特率
=========================================================================
sync		com1 		485  		ttyS0		9600
环境亮度感应	com3 		232  		ttyS1 		19200
TIS     	com4 		485             AP0 		9600
SLCD屏		com5 		485             AP1 		9600
==========================================================================


  ***************************************************************************************************/

#ifndef SERIALCTL_H
#define SERIALCTL_H

#include <QObject>
#include <QTimer>

#include "serialport.h"
#include "log.h"
#include "public/configclass.h"

#define CHANGECOUNT 2    //如果环境光度改变，至少得检测到2次改变值之后才会改变LCD当前的亮度
                         //避免亮度修改太过频繁

#define CHECKLIMMIT     1       //检查次数

#define TIMEINTERVAL                    1000 * 1        //设置定时器的间隔时间,单位ms
#define SEND_SERIALCMD_TIMEINTERVAL     1000 * 200      //发送串口命令的间隔时间,单位us

//LCD 回复状态
#define LCD_ANSWER_ON            0x31            //有回复
#define LCD_ANSWER_OFF           0x30            //无回复

//LCD 背景灯状态
#define LCD_BACKLIGHT_ON        0x31
#define LCD_BACKLIGHT_OFF       0x30

//LCD 状态
#define LCD_INPUTSTATUS_NOSIGNAL        0x30
#define LCD_INPUTSTATUS_DVI1            0x31
#define LCD_INPUTSTATUS_DVI2            0x32

//板载规定好的LCD状态
#define LCD_BOARD_INPUTSTATUS_NOSIGNAL        0x30303030
#define LCD_BOARD_INPUTSTATUS_DVI1            0x46313030
#define LCD_BOARD_INPUTSTATUS_DVI2            0x46323030


typedef struct{
  QTimer              timer;               //定时器，如果一定时间没有收到回复的话，那么重新进行设置
  int                 checkCount;          //检查次数，如果超过 CHANGECOUNT 次，那么证明出错
  quint8              cmd;                 //命令，用来区分
  QList<LCDSTATUS>    panelStatuList;      //收到的LCD回复
  QList<quint16>      panelIDList;         //将要被设置的panelID列表
} CmdStruct;




extern Debug_Config_s g_stDebugConfig;

class SerialCtl : public QObject
{
    Q_OBJECT
    LOG4QT_DECLARE_QCLASS_LOGGER

public:
    explicit SerialCtl(QObject *parent = 0);
    ~SerialCtl();

//    void checkSLCDStatus();

//    void setPhotoToBrightK(float k);
    void init();

signals:
    void lcdAnswerStatus(QList<LCDSTATUS> status);

    void sendSensorData(const qint16);
    void sendLcdSetting(const LcdSettingStruct& lcdSettings);
    void sendLcdState(const QMap<qint16, qint8>& lcdState);

    void openPhotoSPErr();
    void openLcdSPErr();


    void sendSetLcdSettingStatus(const qint8 state);
    void sendSetLcdTraValueStatus(const qint8 state);

    void sendBackLightStatus(qint8 status);

    //发送视频状态,isSendToTis是否要回复给TIS,true是要，false不用
    void sendVideoStatus(const QList<LCDSTATUS>& status, const bool isSendToTis);

//    void videoUnanswer(const QList<LCDSTATUS>& status);


private:
    SerialPort      *displayerSPort;             //slcd之间的通信串口
    PortSettings    disPortSettings;             //串口配置

    SerialPort      *photoSensorSerialPort;      //感光器通信串口，即检测环境亮度设备通信串口
    PortSettings    photoSensorPortSettings;     //串口配置

    SerialPort      *lcdSerialPotr;              //LCD通信串口
    PortSettings    lcdPortSettings;             //串口配置

    LcdSettingStruct lcdSetting;                 //lcd屏的配置

    Configclass configclass;                     //

//    QList<qint16> lcdIDList;

    //下面4个结构体用来贮存设置LCD屏的返回内容，如果有一定时间内没有返回，那么将重新发送设置命令
    CmdStruct       m_brightCmd;                //设置背景灯定时器
    CmdStruct       m_blStatuCmd;               //设置背景灯状态定时器
    CmdStruct       m_queryVideoCmd;            //查询视频状态定时器
    CmdStruct       m_reSetCmd;                 //恢复默认设置定时器

    int repeatCount;                                //如果环境光度改变，至少得检测到2次改变值之后才会改变LCD当前的亮度
                                                    //避免亮度修改太过频繁
    int lastBrightness;                             //最近一次的slcd亮度

    bool isCheckSLcd;                               //是否正在检查SLCD的状态，如果没有的话，那么如果有收到SLCD的状态
                                                    //那么将收到的这一个SLCD的状态传给客户端，如果正在检查SLCD的状态的话
                                                    //就要进行定时器查找，连续一段时间SLCD的状态都没收到的话就表示他们无信息，
                                                    //此时就把这几个无反应的SLCD屏表示为无信号

    bool isTisSelfTest;                                //是否Tis自检

    int m_isMaterDev;                               //是否主设备
    int m_enquiryNum;                               //2台displayers通信的enquiry number,0~255

    QTimer* m_initTimer;                            //初始化定时器
    int m_initCount;                                //初始化次数


    QMap<long, BaudRateType> m_baudRate;

public:
    void sendSyncCommand(qint16 photo);


private slots:
    void recePhotoData(const qint16);
    void checkLcdStatus();
    void checkLcdSetting();

//    void setLcdSettings(const LcdSettingStruct& lcdSettings);
//    void setLcdTraValue(const double lcdK, const int transformValue);

//    void changeLcdBright(const qint16 brightness);
    void changeLcdBright(const qint16 brightness, const QList<quint16>& panelIDList);
    void lcdBackLightCtl(const qint8 cmd, const QList<quint16>& panelIDList);

    void receChangeBriLv(const LcdSettingStruct& lcdSettings);
    void queryVideoStatus(const qint8 cmd);

    //lcd回复亮度设置
    void lcdReplyBrightness_slot(const LcdReplay &lcdReply);

    //lcd回复背景灯状态
    void lcdReplyBLStatus_slot(const LcdReplay &lcdReply);

    //lcd回复恢复默认设置
    void lcdReplyReset_slot(const LcdReplay &lcdReply);

    //lcd回复查询LCD屏状态
    void lcdReplyVideoStatu_slot(const LcdReplay &lcdReply);

    void receBrightnessStatus(const qint8 Status);
    void receBackLightStatus(const qint8 Status);
//    void receVideoStatus(const qint16 status);

    void setSlcdCollectSate(const QList<PanelInfoStruct>& infoList);

    void timeOutSetBirght();
    void timeOutSetBLStatu();
    void timeOutQueryVideo();
    void timeOutReSet();


    void receSyncCommand(const SynchCommand& synCommand);

    //初始化LCD屏的亮度
    void initLcdBright();

    //客户端更新配置
    void updateConfig();

    void TisSelfTest();
};

#endif // SERIALCTL_H
